/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

export const inspectorBlob = '/*\n * Copyright (C) 2014-2017 Apple Inc. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS\'\'\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS\n * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nWebInspector.ScriptSyntaxTree = class ScriptSyntaxTree extends WebInspector.Object\n{\n    constructor(sourceText, script)\n    {\n        super();\n\n        console.assert(script && script instanceof WebInspector.Script, script);\n\n        this._script = script;\n\n        try {\n            let sourceType = this._script.sourceType === WebInspector.Script.SourceType.Module ? \"module\" : \"script\";\n            let esprimaSyntaxTree = esprima.parse(sourceText, {range: true, sourceType});\n            this._syntaxTree = this._createInternalSyntaxTree(esprimaSyntaxTree);\n            this._parsedSuccessfully = true;\n        } catch (error) {\n            this._parsedSuccessfully = false;\n            this._syntaxTree = null;\n            console.error(\"Couldn\'t parse JavaScript File: \" + script.url, error);\n        }\n    }\n\n    // Public\n\n    get parsedSuccessfully()\n    {\n        return this._parsedSuccessfully;\n    }\n\n    forEachNode(callback)\n    {\n        console.assert(this._parsedSuccessfully);\n        if (!this._parsedSuccessfully)\n            return;\n\n        this._recurse(this._syntaxTree, callback, this._defaultParserState());\n    }\n\n    filter(predicate, startNode)\n    {\n        console.assert(startNode && this._parsedSuccessfully);\n        if (!this._parsedSuccessfully)\n            return [];\n\n        var nodes = [];\n        function filter(node, state)\n        {\n            if (predicate(node))\n                nodes.push(node);\n            else\n                state.skipChildNodes = true;\n        }\n\n        this._recurse(startNode, filter, this._defaultParserState());\n\n        return nodes;\n    }\n\n    containersOfOffset(offset)\n    {\n        console.assert(this._parsedSuccessfully);\n        if (!this._parsedSuccessfully)\n            return [];\n\n        let allNodes = [];\n        const start = 0;\n        const end = 1;\n\n        this.forEachNode((node, state) => {\n            if (node.range[end] < offset)\n                state.skipChildNodes = true;\n            if (node.range[start] > offset)\n                state.shouldStopEarly = true;\n            if (node.range[start] <= offset && node.range[end] >= offset)\n                allNodes.push(node);\n        });\n\n        return allNodes;\n    }\n\n    filterByRange(startOffset, endOffset)\n    {\n        console.assert(this._parsedSuccessfully);\n        if (!this._parsedSuccessfully)\n            return [];\n\n        var allNodes = [];\n        var start = 0;\n        var end = 1;\n        function filterForNodesInRange(node, state)\n        {\n            // program start        range            program end\n            // [                 [         ]               ]\n            //            [ ]  [   [        ] ]  [ ]\n\n            // If a node\'s range ends before the range we\'re interested in starts, we don\'t need to search any of its\n            // enclosing ranges, because, by definition, those enclosing ranges are contained within this node\'s range.\n            if (node.range[end] < startOffset)\n                state.skipChildNodes = true;\n\n            // We are only interested in nodes whose start position is within our range.\n            if (startOffset <= node.range[start] && node.range[start] <= endOffset)\n                allNodes.push(node);\n\n            // Once we see nodes that start beyond our range, we can quit traversing the AST. We can do this safely\n            // because we know the AST is traversed using depth first search, so it will traverse into enclosing ranges\n            // before it traverses into adjacent ranges.\n            if (node.range[start] > endOffset)\n                state.shouldStopEarly = true;\n        }\n\n        this.forEachNode(filterForNodesInRange);\n\n        return allNodes;\n    }\n\n    containsNonEmptyReturnStatement(startNode)\n    {\n        console.assert(startNode && this._parsedSuccessfully);\n        if (!this._parsedSuccessfully)\n            return false;\n\n        if (startNode.attachments._hasNonEmptyReturnStatement !== undefined)\n            return startNode.attachments._hasNonEmptyReturnStatement;\n\n        function removeFunctionsFilter(node)\n        {\n            return node.type !== WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression\n                && node.type !== WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration\n                && node.type !== WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression;\n        }\n\n        var nodes = this.filter(removeFunctionsFilter, startNode);\n        var hasNonEmptyReturnStatement = false;\n        var returnStatementType = WebInspector.ScriptSyntaxTree.NodeType.ReturnStatement;\n        for (var node of nodes) {\n            if (node.type === returnStatementType && node.argument) {\n                hasNonEmptyReturnStatement = true;\n                break;\n            }\n        }\n\n        startNode.attachments._hasNonEmptyReturnStatement = hasNonEmptyReturnStatement;\n\n        return hasNonEmptyReturnStatement;\n    }\n\n    static functionReturnDivot(node)\n    {\n        console.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration || node.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression || node.type === WebInspector.ScriptSyntaxTree.NodeType.MethodDefinition || node.type === WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression);\n\n        // COMPATIBILITY (iOS 9): Legacy Backends view the return type as being the opening \"{\" of the function body.\n        // After iOS 9, this is to move to the start of the function statement/expression. See below:\n        // FIXME: Need a better way to determine backend versions. Using DOM.pseudoElement because that was added after iOS 9.\n        if (!DOMAgent.hasEvent(\"pseudoElementAdded\"))\n            return node.body.range[0];\n\n        // \"f\" in \"function\". \"s\" in \"set\". \"g\" in \"get\". First letter in any method name for classes and object literals.\n        // The \"[\" for computed methods in classes and object literals.\n        return node.typeProfilingReturnDivot;\n    }\n\n    updateTypes(nodesToUpdate, callback)\n    {\n        console.assert(RuntimeAgent.getRuntimeTypesForVariablesAtOffsets);\n        console.assert(Array.isArray(nodesToUpdate) && this._parsedSuccessfully);\n\n        if (!this._parsedSuccessfully)\n            return;\n\n        var allRequests = [];\n        var allRequestNodes = [];\n        var sourceID = this._script.id;\n\n        for (var node of nodesToUpdate) {\n            switch (node.type) {\n            case WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration:\n            case WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression:\n            case WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression:\n                for (var param of node.params) {\n                    for (var identifier of this._gatherIdentifiersInDeclaration(param)) {\n                        allRequests.push({\n                            typeInformationDescriptor: WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor.NormalExpression,\n                            sourceID,\n                            divot: identifier.range[0]\n                        });\n                        allRequestNodes.push(identifier);\n                    }\n                }\n\n                allRequests.push({\n                    typeInformationDescriptor: WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor.FunctionReturn,\n                    sourceID,\n                    divot: WebInspector.ScriptSyntaxTree.functionReturnDivot(node)\n                });\n                allRequestNodes.push(node);\n                break;\n            case WebInspector.ScriptSyntaxTree.NodeType.VariableDeclarator:\n                for (var identifier of this._gatherIdentifiersInDeclaration(node.id)) {\n                    allRequests.push({\n                        typeInformationDescriptor: WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor.NormalExpression,\n                        sourceID,\n                        divot: identifier.range[0]\n                    });\n                    allRequestNodes.push(identifier);\n                }\n                break;\n            }\n        }\n\n        console.assert(allRequests.length === allRequestNodes.length);\n\n        function handleTypes(error, typeInformationArray)\n        {\n            if (error)\n                return;\n\n            console.assert(typeInformationArray.length === allRequests.length);\n\n            for (var i = 0; i < typeInformationArray.length; i++) {\n                var node = allRequestNodes[i];\n                var typeInformation = WebInspector.TypeDescription.fromPayload(typeInformationArray[i]);\n                if (allRequests[i].typeInformationDescriptor === WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor.FunctionReturn)\n                    node.attachments.returnTypes = typeInformation;\n                else\n                    node.attachments.types = typeInformation;\n            }\n\n            callback(allRequestNodes);\n        }\n\n        this._script.target.RuntimeAgent.getRuntimeTypesForVariablesAtOffsets(allRequests, handleTypes);\n    }\n\n    // Private\n\n    _gatherIdentifiersInDeclaration(node)\n    {\n        function gatherIdentifiers(node)\n        {\n            switch (node.type) {\n                case WebInspector.ScriptSyntaxTree.NodeType.Identifier:\n                    return [node];\n                case WebInspector.ScriptSyntaxTree.NodeType.Property:\n                    return gatherIdentifiers(node.value);\n                case WebInspector.ScriptSyntaxTree.NodeType.ObjectPattern:\n                    var identifiers = [];\n                    for (var property of node.properties) {\n                        for (var identifier of gatherIdentifiers(property))\n                            identifiers.push(identifier);\n                    }\n                    return identifiers;\n                case WebInspector.ScriptSyntaxTree.NodeType.ArrayPattern:\n                    var identifiers = [];\n                    for (var element of node.elements) {\n                        for (var identifier of gatherIdentifiers(element))\n                            identifiers.push(identifier);\n                    }\n                    return identifiers;\n                case WebInspector.ScriptSyntaxTree.NodeType.AssignmentPattern:\n                    return gatherIdentifiers(node.left);\n                case WebInspector.ScriptSyntaxTree.NodeType.RestElement:\n                case WebInspector.ScriptSyntaxTree.NodeType.RestProperty:\n                    return gatherIdentifiers(node.argument);\n                default:\n                    console.assert(false, \"Unexpected node type in variable declarator: \" + node.type);\n                    return [];\n            }\n        }\n\n        console.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.Identifier || node.type === WebInspector.ScriptSyntaxTree.NodeType.ObjectPattern || node.type === WebInspector.ScriptSyntaxTree.NodeType.ArrayPattern || node.type === WebInspector.ScriptSyntaxTree.NodeType.RestElement || node.type === WebInspector.ScriptSyntaxTree.NodeType.RestProperty);\n\n        return gatherIdentifiers(node);\n    }\n\n    _defaultParserState()\n    {\n        return {\n            shouldStopEarly: false,\n            skipChildNodes: false\n        };\n    }\n\n    _recurse(node, callback, state)\n    {\n        if (!node)\n            return;\n\n        if (state.shouldStopEarly || state.skipChildNodes)\n            return;\n\n        callback(node, state);\n\n        switch (node.type) {\n        case WebInspector.ScriptSyntaxTree.NodeType.AssignmentExpression:\n            this._recurse(node.left, callback, state);\n            this._recurse(node.right, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ArrayExpression:\n        case WebInspector.ScriptSyntaxTree.NodeType.ArrayPattern:\n            this._recurseArray(node.elements, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.AssignmentPattern:\n            this._recurse(node.left, callback, state);\n            this._recurse(node.right, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.AwaitExpression:\n            this._recurse(node.argument, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.BlockStatement:\n            this._recurseArray(node.body, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.BinaryExpression:\n            this._recurse(node.left, callback, state);\n            this._recurse(node.right, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.BreakStatement:\n            this._recurse(node.label, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.CatchClause:\n            this._recurse(node.param, callback, state);\n            this._recurse(node.body, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.CallExpression:\n            this._recurse(node.callee, callback, state);\n            this._recurseArray(node.arguments, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ClassBody:\n            this._recurseArray(node.body, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ClassDeclaration:\n        case WebInspector.ScriptSyntaxTree.NodeType.ClassExpression:\n            this._recurse(node.id, callback, state);\n            this._recurse(node.superClass, callback, state);\n            this._recurse(node.body, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ContinueStatement:\n            this._recurse(node.label, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.DoWhileStatement:\n            this._recurse(node.body, callback, state);\n            this._recurse(node.test, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ExpressionStatement:\n            this._recurse(node.expression, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ForStatement:\n            this._recurse(node.init, callback, state);\n            this._recurse(node.test, callback, state);\n            this._recurse(node.update, callback, state);\n            this._recurse(node.body, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ForInStatement:\n        case WebInspector.ScriptSyntaxTree.NodeType.ForOfStatement:\n            this._recurse(node.left, callback, state);\n            this._recurse(node.right, callback, state);\n            this._recurse(node.body, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration:\n        case WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression:\n        case WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression:\n            this._recurse(node.id, callback, state);\n            this._recurseArray(node.params, callback, state);\n            this._recurse(node.body, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.IfStatement:\n            this._recurse(node.test, callback, state);\n            this._recurse(node.consequent, callback, state);\n            this._recurse(node.alternate, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.LabeledStatement:\n            this._recurse(node.label, callback, state);\n            this._recurse(node.body, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.LogicalExpression:\n            this._recurse(node.left, callback, state);\n            this._recurse(node.right, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.MemberExpression:\n            this._recurse(node.object, callback, state);\n            this._recurse(node.property, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.MethodDefinition:\n            this._recurse(node.key, callback, state);\n            this._recurse(node.value, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.NewExpression:\n            this._recurse(node.callee, callback, state);\n            this._recurseArray(node.arguments, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ObjectExpression:\n        case WebInspector.ScriptSyntaxTree.NodeType.ObjectPattern:\n            this._recurseArray(node.properties, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.Program:\n            this._recurseArray(node.body, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.Property:\n            this._recurse(node.key, callback, state);\n            this._recurse(node.value, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.RestElement:\n            this._recurse(node.argument, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.RestProperty:\n            this._recurse(node.argument, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ReturnStatement:\n            this._recurse(node.argument, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.SequenceExpression:\n            this._recurseArray(node.expressions, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.SpreadElement:\n            this._recurse(node.argument, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.SpreadProperty:\n            this._recurse(node.argument, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.SwitchStatement:\n            this._recurse(node.discriminant, callback, state);\n            this._recurseArray(node.cases, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.SwitchCase:\n            this._recurse(node.test, callback, state);\n            this._recurseArray(node.consequent, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ConditionalExpression:\n            this._recurse(node.test, callback, state);\n            this._recurse(node.consequent, callback, state);\n            this._recurse(node.alternate, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.TaggedTemplateExpression:\n            this._recurse(node.tag, callback, state);\n            this._recurse(node.quasi, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.TemplateLiteral:\n            this._recurseArray(node.quasis, callback, state);\n            this._recurseArray(node.expressions, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ThrowStatement:\n            this._recurse(node.argument, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.TryStatement:\n            this._recurse(node.block, callback, state);\n            this._recurse(node.handler, callback, state);\n            this._recurse(node.finalizer, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.UnaryExpression:\n            this._recurse(node.argument, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.UpdateExpression:\n            this._recurse(node.argument, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.VariableDeclaration:\n            this._recurseArray(node.declarations, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.VariableDeclarator:\n            this._recurse(node.id, callback, state);\n            this._recurse(node.init, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.WhileStatement:\n            this._recurse(node.test, callback, state);\n            this._recurse(node.body, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.WithStatement:\n            this._recurse(node.object, callback, state);\n            this._recurse(node.body, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.YieldExpression:\n            this._recurse(node.argument, callback, state);\n            break;\n\n        // Modules.\n\n        case WebInspector.ScriptSyntaxTree.NodeType.ExportAllDeclaration:\n            this._recurse(node.source, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ExportNamedDeclaration:\n            this._recurse(node.declaration, callback, state);\n            this._recurseArray(node.specifiers, callback, state);\n            this._recurse(node.source, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ExportDefaultDeclaration:\n            this._recurse(node.declaration, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ExportSpecifier:\n            this._recurse(node.local, callback, state);\n            this._recurse(node.exported, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ImportDeclaration:\n            this._recurseArray(node.specifiers, callback, state);\n            this._recurse(node.source, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ImportDefaultSpecifier:\n            this._recurse(node.local, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ImportNamespaceSpecifier:\n            this._recurse(node.local, callback, state);\n            break;\n        case WebInspector.ScriptSyntaxTree.NodeType.ImportSpecifier:\n            this._recurse(node.imported, callback, state);\n            this._recurse(node.local, callback, state);\n            break;\n\n        // All the leaf nodes go here.\n        case WebInspector.ScriptSyntaxTree.NodeType.DebuggerStatement:\n        case WebInspector.ScriptSyntaxTree.NodeType.EmptyStatement:\n        case WebInspector.ScriptSyntaxTree.NodeType.Identifier:\n        case WebInspector.ScriptSyntaxTree.NodeType.Import:\n        case WebInspector.ScriptSyntaxTree.NodeType.Literal:\n        case WebInspector.ScriptSyntaxTree.NodeType.MetaProperty:\n        case WebInspector.ScriptSyntaxTree.NodeType.Super:\n        case WebInspector.ScriptSyntaxTree.NodeType.ThisExpression:\n        case WebInspector.ScriptSyntaxTree.NodeType.TemplateElement:\n            break;\n        }\n\n        state.skipChildNodes = false;\n    }\n\n    _recurseArray(array, callback, state)\n    {\n        for (var node of array)\n            this._recurse(node, callback, state);\n    }\n\n    // This function translates from esprima\'s Abstract Syntax Tree to ours.\n    // Mostly, this is just the identity function. We\'ve added an extra typeProfilingReturnDivot property for functions/methods.\n    // Our AST complies with the Mozilla parser API:\n    // https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API\n    _createInternalSyntaxTree(node)\n    {\n        if (!node)\n            return null;\n\n        var result = null;\n        switch (node.type) {\n        case \"ArrayExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ArrayExpression,\n                elements: node.elements.map(this._createInternalSyntaxTree, this)\n            };\n            break;\n        case \"ArrayPattern\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ArrayPattern,\n                elements: node.elements.map(this._createInternalSyntaxTree, this)\n            };\n            break;\n        case \"ArrowFunctionExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression,\n                id: this._createInternalSyntaxTree(node.id),\n                params: node.params.map(this._createInternalSyntaxTree, this),\n                body: this._createInternalSyntaxTree(node.body),\n                generator: node.generator,\n                expression: node.expression, // Boolean indicating if the body a single expression or a block statement.\n                async: node.async,\n                typeProfilingReturnDivot: node.range[0]\n            };\n            break;\n        case \"AssignmentExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.AssignmentExpression,\n                operator: node.operator,\n                left: this._createInternalSyntaxTree(node.left),\n                right: this._createInternalSyntaxTree(node.right)\n            };\n            break;\n        case \"AssignmentPattern\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.AssignmentPattern,\n                left: this._createInternalSyntaxTree(node.left),\n                right: this._createInternalSyntaxTree(node.right),\n            };\n            break;\n        case \"AwaitExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.AwaitExpression,\n                argument: this._createInternalSyntaxTree(node.argument),\n            };\n            break;\n        case \"BlockStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.BlockStatement,\n                body: node.body.map(this._createInternalSyntaxTree, this)\n            };\n            break;\n        case \"BinaryExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.BinaryExpression,\n                operator: node.operator,\n                left: this._createInternalSyntaxTree(node.left),\n                right: this._createInternalSyntaxTree(node.right)\n            };\n            break;\n        case \"BreakStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.BreakStatement,\n                label: this._createInternalSyntaxTree(node.label)\n            };\n            break;\n        case \"CallExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.CallExpression,\n                callee: this._createInternalSyntaxTree(node.callee),\n                arguments: node.arguments.map(this._createInternalSyntaxTree, this)\n            };\n            break;\n        case \"CatchClause\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.CatchClause,\n                param: this._createInternalSyntaxTree(node.param),\n                body: this._createInternalSyntaxTree(node.body)\n            };\n            break;\n        case \"ClassBody\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ClassBody,\n                body: node.body.map(this._createInternalSyntaxTree, this)\n            };\n            break;\n        case \"ClassDeclaration\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ClassDeclaration,\n                id: this._createInternalSyntaxTree(node.id),\n                superClass: this._createInternalSyntaxTree(node.superClass),\n                body: this._createInternalSyntaxTree(node.body),\n            };\n            break;\n        case \"ClassExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ClassExpression,\n                id: this._createInternalSyntaxTree(node.id),\n                superClass: this._createInternalSyntaxTree(node.superClass),\n                body: this._createInternalSyntaxTree(node.body),\n            };\n            break;\n        case \"ConditionalExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ConditionalExpression,\n                test: this._createInternalSyntaxTree(node.test),\n                consequent: this._createInternalSyntaxTree(node.consequent),\n                alternate: this._createInternalSyntaxTree(node.alternate)\n            };\n            break;\n        case \"ContinueStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ContinueStatement,\n                label: this._createInternalSyntaxTree(node.label)\n            };\n            break;\n        case \"DoWhileStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.DoWhileStatement,\n                body: this._createInternalSyntaxTree(node.body),\n                test: this._createInternalSyntaxTree(node.test)\n            };\n            break;\n        case \"DebuggerStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.DebuggerStatement\n            };\n            break;\n        case \"EmptyStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.EmptyStatement\n            };\n            break;\n        case \"ExpressionStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ExpressionStatement,\n                expression: this._createInternalSyntaxTree(node.expression)\n            };\n            break;\n        case \"ForStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ForStatement,\n                init: this._createInternalSyntaxTree(node.init),\n                test: this._createInternalSyntaxTree(node.test),\n                update: this._createInternalSyntaxTree(node.update),\n                body: this._createInternalSyntaxTree(node.body)\n            };\n            break;\n        case \"ForInStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ForInStatement,\n                left: this._createInternalSyntaxTree(node.left),\n                right: this._createInternalSyntaxTree(node.right),\n                body: this._createInternalSyntaxTree(node.body)\n            };\n            break;\n        case \"ForOfStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ForOfStatement,\n                left: this._createInternalSyntaxTree(node.left),\n                right: this._createInternalSyntaxTree(node.right),\n                body: this._createInternalSyntaxTree(node.body)\n            };\n            break;\n        case \"FunctionDeclaration\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration,\n                id: this._createInternalSyntaxTree(node.id),\n                params: node.params.map(this._createInternalSyntaxTree, this),\n                body: this._createInternalSyntaxTree(node.body),\n                generator: node.generator,\n                async: node.async,\n                typeProfilingReturnDivot: node.range[0]\n            };\n            break;\n        case \"FunctionExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression,\n                id: this._createInternalSyntaxTree(node.id),\n                params: node.params.map(this._createInternalSyntaxTree, this),\n                body: this._createInternalSyntaxTree(node.body),\n                generator: node.generator,\n                async: node.async,\n                typeProfilingReturnDivot: node.range[0] // This may be overridden in the Property AST node.\n            };\n            break;\n        case \"Identifier\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.Identifier,\n                name: node.name\n            };\n            break;\n        case \"IfStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.IfStatement,\n                test: this._createInternalSyntaxTree(node.test),\n                consequent: this._createInternalSyntaxTree(node.consequent),\n                alternate: this._createInternalSyntaxTree(node.alternate)\n            };\n            break;\n        case \"Literal\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.Literal,\n                value: node.value,\n                raw: node.raw\n            };\n            break;\n        case \"LabeledStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.LabeledStatement,\n                label: this._createInternalSyntaxTree(node.label),\n                body: this._createInternalSyntaxTree(node.body)\n            };\n            break;\n        case \"LogicalExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.LogicalExpression,\n                left: this._createInternalSyntaxTree(node.left),\n                right: this._createInternalSyntaxTree(node.right),\n                operator: node.operator\n            };\n            break;\n        case \"MemberExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.MemberExpression,\n                object: this._createInternalSyntaxTree(node.object),\n                property: this._createInternalSyntaxTree(node.property),\n                computed: node.computed\n            };\n            break;\n        case \"MetaProperty\":\n            // i.e: new.target produces {meta: \"new\", property: \"target\"}\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.MetaProperty,\n                meta: this._createInternalSyntaxTree(node.meta),\n                property: this._createInternalSyntaxTree(node.property),\n            };\n            break;\n        case \"MethodDefinition\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.MethodDefinition,\n                key: this._createInternalSyntaxTree(node.key),\n                value: this._createInternalSyntaxTree(node.value),\n                computed: node.computed,\n                kind: node.kind,\n                static: node.static\n            };\n            result.value.typeProfilingReturnDivot = node.range[0]; // \"g\" in \"get\" or \"s\" in \"set\" or \"[\" in \"[\'computed\']\" or \"m\" in \"methodName\".\n            break;\n        case \"NewExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.NewExpression,\n                callee: this._createInternalSyntaxTree(node.callee),\n                arguments: node.arguments.map(this._createInternalSyntaxTree, this)\n            };\n            break;\n        case \"ObjectExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ObjectExpression,\n                properties: node.properties.map(this._createInternalSyntaxTree, this)\n            };\n            break;\n        case \"ObjectPattern\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ObjectPattern,\n                properties: node.properties.map(this._createInternalSyntaxTree, this)\n            };\n            break;\n        case \"Program\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.Program,\n                sourceType: node.sourceType,\n                body: node.body.map(this._createInternalSyntaxTree, this)\n            };\n            break;\n        case \"Property\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.Property,\n                key: this._createInternalSyntaxTree(node.key),\n                value: this._createInternalSyntaxTree(node.value),\n                kind: node.kind,\n                method: node.method,\n                computed: node.computed\n            };\n            if (result.kind === \"get\" || result.kind === \"set\" || result.method)\n                result.value.typeProfilingReturnDivot = node.range[0];  // \"g\" in \"get\" or \"s\" in \"set\" or \"[\" in \"[\'computed\']\" method or \"m\" in \"methodName\".\n            break;\n        case \"RestElement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.RestElement,\n                argument: this._createInternalSyntaxTree(node.argument)\n            };\n            break;\n        case \"RestProperty\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.RestProperty,\n                argument: this._createInternalSyntaxTree(node.argument),\n            };\n            break;\n        case \"ReturnStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ReturnStatement,\n                argument: this._createInternalSyntaxTree(node.argument)\n            };\n            break;\n        case \"SequenceExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.SequenceExpression,\n                expressions: node.expressions.map(this._createInternalSyntaxTree, this)\n            };\n            break;\n        case \"SpreadElement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.SpreadElement,\n                argument: this._createInternalSyntaxTree(node.argument),\n            };\n            break;\n        case \"SpreadProperty\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.SpreadProperty,\n                argument: this._createInternalSyntaxTree(node.argument),\n            };\n            break;\n        case \"Super\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.Super\n            };\n            break;\n        case \"SwitchStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.SwitchStatement,\n                discriminant: this._createInternalSyntaxTree(node.discriminant),\n                cases: node.cases.map(this._createInternalSyntaxTree, this)\n            };\n            break;\n        case \"SwitchCase\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.SwitchCase,\n                test: this._createInternalSyntaxTree(node.test),\n                consequent: node.consequent.map(this._createInternalSyntaxTree, this)\n            };\n            break;\n        case \"TaggedTemplateExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.TaggedTemplateExpression,\n                tag: this._createInternalSyntaxTree(node.tag),\n                quasi: this._createInternalSyntaxTree(node.quasi)\n            };\n            break;\n        case \"TemplateElement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.TemplateElement,\n                value: node.value,\n                tail: node.tail\n            };\n            break;\n        case \"TemplateLiteral\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.TemplateLiteral,\n                quasis: node.quasis.map(this._createInternalSyntaxTree, this),\n                expressions: node.expressions.map(this._createInternalSyntaxTree, this)\n            };\n            break;\n        case \"ThisExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ThisExpression\n            };\n            break;\n        case \"ThrowStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ThrowStatement,\n                argument: this._createInternalSyntaxTree(node.argument)\n            };\n            break;\n        case \"TryStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.TryStatement,\n                block: this._createInternalSyntaxTree(node.block),\n                handler: this._createInternalSyntaxTree(node.handler),\n                finalizer: this._createInternalSyntaxTree(node.finalizer)\n            };\n            break;\n        case \"UnaryExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.UnaryExpression,\n                operator: node.operator,\n                argument: this._createInternalSyntaxTree(node.argument)\n            };\n            break;\n        case \"UpdateExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.UpdateExpression,\n                operator: node.operator,\n                prefix: node.prefix,\n                argument: this._createInternalSyntaxTree(node.argument)\n            };\n            break;\n        case \"VariableDeclaration\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.VariableDeclaration,\n                declarations: node.declarations.map(this._createInternalSyntaxTree, this),\n                kind: node.kind\n            };\n            break;\n        case \"VariableDeclarator\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.VariableDeclarator,\n                id: this._createInternalSyntaxTree(node.id),\n                init: this._createInternalSyntaxTree(node.init)\n            };\n            break;\n        case \"WhileStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.WhileStatement,\n                test: this._createInternalSyntaxTree(node.test),\n                body: this._createInternalSyntaxTree(node.body)\n            };\n            break;\n        case \"WithStatement\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.WithStatement,\n                object: this._createInternalSyntaxTree(node.object),\n                body: this._createInternalSyntaxTree(node.body)\n            };\n            break;\n        case \"YieldExpression\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.YieldExpression,\n                argument: this._createInternalSyntaxTree(node.argument),\n                delegate: node.delegate\n            };\n            break;\n\n        // Modules.\n\n        case \"ExportAllDeclaration\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ExportAllDeclaration,\n                source: this._createInternalSyntaxTree(node.source),\n            };\n            break;\n        case \"ExportNamedDeclaration\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ExportNamedDeclaration,\n                declaration: this._createInternalSyntaxTree(node.declaration),\n                specifiers: node.specifiers.map(this._createInternalSyntaxTree, this),\n                source: this._createInternalSyntaxTree(node.source),\n            };\n            break;\n        case \"ExportDefaultDeclaration\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ExportDefaultDeclaration,\n                declaration: this._createInternalSyntaxTree(node.declaration),\n            };\n            break;\n        case \"ExportSpecifier\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ExportSpecifier,\n                local: this._createInternalSyntaxTree(node.local),\n                exported: this._createInternalSyntaxTree(node.exported),\n            };\n            break;\n        case \"Import\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.Import,\n            };\n            break;\n        case \"ImportDeclaration\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ImportDeclaration,\n                specifiers: node.specifiers.map(this._createInternalSyntaxTree, this),\n                source: this._createInternalSyntaxTree(node.source),\n            };\n            break;\n        case \"ImportDefaultSpecifier\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ImportDefaultSpecifier,\n                local: this._createInternalSyntaxTree(node.local),\n            };\n            break;\n        case \"ImportNamespaceSpecifier\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ImportNamespaceSpecifier,\n                local: this._createInternalSyntaxTree(node.local),\n            };\n            break;\n        case \"ImportSpecifier\":\n            result = {\n                type: WebInspector.ScriptSyntaxTree.NodeType.ImportSpecifier,\n                imported: this._createInternalSyntaxTree(node.imported),\n                local: this._createInternalSyntaxTree(node.local),\n            };\n            break;\n\n        default:\n            console.error(\"Unsupported Syntax Tree Node: \" + node.type, node);\n            return null;\n        }\n\n        result.range = node.range;\n        // This is an object for which you can add fields to an AST node without worrying about polluting the syntax-related fields of the node.\n        result.attachments = {};\n\n        return result;\n    }\n};\n\n// This should be kept in sync with an enum in JavaSciptCore/runtime/TypeProfiler.h\nWebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor = {\n    NormalExpression: 1,\n    FunctionReturn: 2\n};\n\nWebInspector.ScriptSyntaxTree.NodeType = {\n    ArrayExpression: Symbol(\"array-expression\"),\n    ArrayPattern: Symbol(\"array-pattern\"),\n    ArrowFunctionExpression: Symbol(\"arrow-function-expression\"),\n    AssignmentExpression: Symbol(\"assignment-expression\"),\n    AssignmentPattern: Symbol(\"assignment-pattern\"),\n    AwaitExpression: Symbol(\"await-expression\"),\n    BinaryExpression: Symbol(\"binary-expression\"),\n    BlockStatement: Symbol(\"block-statement\"),\n    BreakStatement: Symbol(\"break-statement\"),\n    CallExpression: Symbol(\"call-expression\"),\n    CatchClause: Symbol(\"catch-clause\"),\n    ClassBody: Symbol(\"class-body\"),\n    ClassDeclaration: Symbol(\"class-declaration\"),\n    ClassExpression: Symbol(\"class-expression\"),\n    ConditionalExpression: Symbol(\"conditional-expression\"),\n    ContinueStatement: Symbol(\"continue-statement\"),\n    DebuggerStatement: Symbol(\"debugger-statement\"),\n    DoWhileStatement: Symbol(\"do-while-statement\"),\n    EmptyStatement: Symbol(\"empty-statement\"),\n    ExportAllDeclaration: Symbol(\"export-all-declaration\"),\n    ExportDefaultDeclaration: Symbol(\"export-default-declaration\"),\n    ExportNamedDeclaration: Symbol(\"export-named-declaration\"),\n    ExportSpecifier: Symbol(\"export-specifier\"),\n    ExpressionStatement: Symbol(\"expression-statement\"),\n    ForInStatement: Symbol(\"for-in-statement\"),\n    ForOfStatement: Symbol(\"for-of-statement\"),\n    ForStatement: Symbol(\"for-statement\"),\n    FunctionDeclaration: Symbol(\"function-declaration\"),\n    FunctionExpression: Symbol(\"function-expression\"),\n    Identifier: Symbol(\"identifier\"),\n    IfStatement: Symbol(\"if-statement\"),\n    Import: Symbol(\"import\"),\n    ImportDeclaration: Symbol(\"import-declaration\"),\n    ImportDefaultSpecifier: Symbol(\"import-default-specifier\"),\n    ImportNamespaceSpecifier: Symbol(\"import-namespace-specifier\"),\n    ImportSpecifier: Symbol(\"import-specifier\"),\n    LabeledStatement: Symbol(\"labeled-statement\"),\n    Literal: Symbol(\"literal\"),\n    LogicalExpression: Symbol(\"logical-expression\"),\n    MemberExpression: Symbol(\"member-expression\"),\n    MetaProperty: Symbol(\"meta-property\"),\n    MethodDefinition: Symbol(\"method-definition\"),\n    NewExpression: Symbol(\"new-expression\"),\n    ObjectExpression: Symbol(\"object-expression\"),\n    ObjectPattern: Symbol(\"object-pattern\"),\n    Program: Symbol(\"program\"),\n    Property: Symbol(\"property\"),\n    RestElement: Symbol(\"rest-element\"),\n    RestProperty: Symbol(\"rest-property\"),\n    ReturnStatement: Symbol(\"return-statement\"),\n    SequenceExpression: Symbol(\"sequence-expression\"),\n    SpreadElement: Symbol(\"spread-element\"),\n    SpreadProperty: Symbol(\"spread-property\"),\n    Super: Symbol(\"super\"),\n    SwitchCase: Symbol(\"switch-case\"),\n    SwitchStatement: Symbol(\"switch-statement\"),\n    TaggedTemplateExpression: Symbol(\"tagged-template-expression\"),\n    TemplateElement: Symbol(\"template-element\"),\n    TemplateLiteral: Symbol(\"template-literal\"),\n    ThisExpression: Symbol(\"this-expression\"),\n    ThrowStatement: Symbol(\"throw-statement\"),\n    TryStatement: Symbol(\"try-statement\"),\n    UnaryExpression: Symbol(\"unary-expression\"),\n    UpdateExpression: Symbol(\"update-expression\"),\n    VariableDeclaration: Symbol(\"variable-declaration\"),\n    VariableDeclarator: Symbol(\"variable-declarator\"),\n    WhileStatement: Symbol(\"while-statement\"),\n    WithStatement: Symbol(\"with-statement\"),\n    YieldExpression: Symbol(\"yield-expression\"),\n};\n';
